package com.hangwei.aicabinet.util;

/**
 * Created by 张龙臣 on 2018/9/15.
 */

public class CRCUtil {


    /**
     * crc 16查表发
     *
     * @param data  指令的16进制字节数组
     * @param offset 从第多少位开始校验
     * @param len 校验的字节长度  （校验部分字符串长度 / 2）
     * @return
     */
    public static byte[] crcTable(byte[] data, int offset, int len) {
        int crc = 0xffff;
        int end = offset + len;
        for (int i = offset; i < end; i++) {
            crc = ((crc << 4) | ((data[i] >> 4) & 0xf)) ^ CRC_TABLE[crc >> 12];
            crc &= 0xffff;
            crc = ((crc << 4) | (data[i] & 0xf)) ^ CRC_TABLE[crc >> 12];
            crc &= 0xffff;
        }
        return long2bytes(crc, 2);
    }

    private static final int[] CRC_TABLE = {
            0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a,
            0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef
    };

    /**
     * int类型转成高位在前的字节数组
     *
     * @param ori
     * @param arrayAmount 字节数组长度
     * @return
     */
    private static byte[] long2bytes(long ori, int arrayAmount) {
        byte[] bytes = new byte[arrayAmount];
        for (int i = 0; i < arrayAmount; i++) {
            // 高位在前
            bytes[i] = (byte) ((ori >> (arrayAmount - i - 1) * 8) & 0xff);
        }
        return bytes;
    }
}